#include "stm32f10x_adc.h"
#include "stm32f10x_spi.h"
#include "stm32f10x.h"
#include "prj_type.h"
#include "TR700Driver.h"
#include "project.h"


// ***************************************************************************
// 连续激光器控制
#ifdef CONFIG_ADC_TOTAL_CH
	#define ADC_TOTAL_CH    (CONFIG_ADC_TOTAL_CH)
#else
	#define ADC_TOTAL_CH    (2)       // 总共有几个听到
#endif
#define ADC_SAMPLE_PRE_CH  (200)  // 每个通道采样数

// 预留一个通道值，防范式变成
uint16_t g_adc_convert[(ADC_TOTAL_CH + 1) * ADC_SAMPLE_PRE_CH];
volatile uint16_t g_adc[ADC_SAMPLE_PRE_CH];			///<得到ADCConvertedValue里某通道的连续采样AD值
// uint16_t g_adc_convert[2000];


/*
g_adc_convert 值

假设只有2个通道，处于循环转换模式，分别映射到ChA和ChB上

注意：
如上所说的2个通道并不是STM32的Ch1、Ch2，而是使用 ADC_RegularChannelConfig() 对
所有需要转换的通道进行的排序
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 1, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 2, ADC_SampleTime_55Cycles5);
上面的操作时的 ADC 转换控制器采用时分方式 __交替__ 转换 Ch3、Ch9，
Ch3 ---> ChA
Ch9 ---> ChB

转换序列如下

第N次采样   对应通道
00    <--     ChA
01      <--     ChB
02    <--     ChA
03      <--     ChB
04    <--     ChA
05      <--     ChB
06    <--     ChA
07      <--     ChB
      ......
3998    <--     ChA
3999      <--     ChB
*/

void ADC_Configuration()
{
	// TODO 可以自由配置通道数
	ADC_InitTypeDef ADC_InitStructure;
	DMA_InitTypeDef DMA_InitStructure;

	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0 | GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AIN;
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	//ADC1 采样wave 等其他共5个通道，用DMA通道1
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	// Enable ADC1 and GPIOC clock
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE);

	// DMA1 channel1 configuration ----------------------------------------------
	DMA_DeInit(DMA1_Channel1);
	DMA_InitStructure.DMA_PeripheralBaseAddr	= (uint32_t) & (ADC1->DR); //ADC1_DR_Address;
	DMA_InitStructure.DMA_MemoryBaseAddr		= (uint32_t)&g_adc_convert;
	DMA_InitStructure.DMA_DIR			= DMA_DIR_PeripheralSRC;
	DMA_InitStructure.DMA_BufferSize		= ADC_TOTAL_CH * ADC_SAMPLE_PRE_CH;//ADC_BUF;//two adc channel,cycle sampling 11 times
	DMA_InitStructure.DMA_PeripheralInc		= DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc			= DMA_MemoryInc_Enable;//g_这样可以寻址adc_convert
	DMA_InitStructure.DMA_PeripheralDataSize	= DMA_PeripheralDataSize_HalfWord;
	DMA_InitStructure.DMA_MemoryDataSize		= DMA_MemoryDataSize_HalfWord;
	DMA_InitStructure.DMA_Mode			= DMA_Mode_Circular;
	DMA_InitStructure.DMA_Priority			= DMA_Priority_High;
	DMA_InitStructure.DMA_M2M			= DMA_M2M_Disable;

	DMA_Init(DMA1_Channel1, &DMA_InitStructure);
	DMA_Cmd(DMA1_Channel1, ENABLE);// Enable DMA1 channel1


	ADC_InitStructure.ADC_Mode			= ADC_Mode_Independent;
	ADC_InitStructure.ADC_ScanConvMode		= ENABLE;
	ADC_InitStructure.ADC_ContinuousConvMode	= ENABLE;
	ADC_InitStructure.ADC_ExternalTrigConv		= ADC_ExternalTrigConv_None;
	ADC_InitStructure.ADC_DataAlign			= ADC_DataAlign_Right;
	ADC_InitStructure.ADC_NbrOfChannel		= 2;

	ADC_Init(ADC1, &ADC_InitStructure);

	ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 2, ADC_SampleTime_55Cycles5);
	//ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 1, ADC_SampleTime_55Cycles5);


	ADC_DMACmd(ADC1, ENABLE);
	ADC_Cmd(ADC1, ENABLE);
	ADC_ResetCalibration(ADC1);						// Enable ADC1 reset calibration register
	while(ADC_GetResetCalibrationStatus(ADC1));		// Check the end of ADC1 reset calibration register
	ADC_StartCalibration(ADC1);						// Start ADC1 calibration
	while(ADC_GetCalibrationStatus(ADC1));			// Check the end of ADC1 calibration
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);			// Start ADC1 Software Conversion
}


/****************************************************************************
数模转换部分
*****************************************************************************/

/**
 * @brief	制定AD通道获取AD数据
 * @param
 	chx = 0 电池，chx = 1 功率控制
 * @retval\n	NULL
 * @remarks
 */

uint16_t GetAD(uint8_t chx)
{
	uint32_t i, k, start = 0;
	uint32_t tmp;
	float ave;

	if(chx == 0) {
		start = 0;
	} else if(chx == 1) {
		start = 1;
	} else {
		return 0;
	}
	for(k = 0, i = start; i < ADC_TOTAL_CH * ADC_SAMPLE_PRE_CH; i += ADC_TOTAL_CH) {
		g_adc[k] = g_adc_convert[i];
		k++;
	}

	tmp = 0;
	for(i = 0; i < ADC_SAMPLE_PRE_CH; i++) {
		tmp += g_adc[i];
	}
	ave = (float)tmp / ADC_SAMPLE_PRE_CH;

	return (uint16_t)ave;
}
